﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ThermalEquipmentDesign.Model.Condenser.VerticalPipeR717
{
    class VerticalPipeR717Model
    {
        VerticalPipeR717Result res = new VerticalPipeR717Result();
        VerticalPipeR717 condenser;

        /// <summary>
        /// Calcualte Vertical Pipe Condenser
        /// </summary>
        /// <param name="con">VerticalPipeR717 object</param>
        /// <returns>VerticalPipeR717Result object</returns>
        public VerticalPipeR717Result ImplementCalculation(VerticalPipeR717 con)
        {
            condenser = con;
            res.dbHeatCapacity = CalculateHeatCapacity();
            res.dbOutWaterTemperature = CalculateOutWaterTemperature();
            res.dbDiffTemp = CalculateDiffTemp();
            res.dbWaterFlow = CalculateWaterFlow();
            res.dbAverageTemp = CalculateAverageTemp();
            res.dbGalileCoefficient = CalculateGalileCoefficient();
            res.dbReCoefficient = CalculateReCoefficient();
            res.dbNusseltCoefficient = CalculateNusseltCoefficient();
            res.dbHeatCoefficient = CalculateHeatCoefficient();
            res.dbHeatDensity = CalculateHeatDensity();
            res.dbHeatTransferArea = CalculateHeatTransferArea();
            res.dbPipeArea = CalculatePipeArea();
            res.dbDiagonal = CalculateDiagonal();
            res.dbPipeNumber = CalculatePipeNumber();
            res.dbPipeDiameter = CalculatePipeDiameter();
            res.dbPipeLenght = CalculatePipeLenght();
            return res;
        }

        /// <summary>
        /// Calculate heat capacity
        /// </summary>
        /// <returns>heat capacity</returns>
        private double CalculateHeatCapacity()
        {
            double Qk = 1.2 * condenser.dbColdProductivity;
            return Math.Round(Qk,2);
        }

        /// <summary>
        /// Calculate temperature of ouputted water
        /// </summary>
        /// <returns></returns>
        private double CalculateOutWaterTemperature()
        {
            double t2 = condenser.dbWaterTemperature + condenser.dbDegreeIncreaseTemp;
            return Math.Round(t2,2);
        }

        /// <summary>
        /// Calculate logarit different teperature
        /// </summary>
        /// <returns>logarit different teperature</returns>
        private double CalculateDiffTemp()
        {
            double ln = Math.Log((condenser.dbCondensationTemperature - condenser.dbWaterTemperature) / (condenser.dbCondensationTemperature - res.dbOutWaterTemperature));
            double deltat = condenser.dbDegreeIncreaseTemp / ln;
            return Math.Round(deltat,2);
        }

        /// <summary>
        /// Calculate cool water flow
        /// </summary>
        /// <returns>cool water flow</returns>
        private double CalculateWaterFlow()
        {
            double Mn = res.dbHeatCapacity / (condenser.dbWaterThermalCapacity * condenser.dbDegreeIncreaseTemp);
            return Math.Round(Mn,2);
        }

        /// <summary>
        /// Calculate average temperature of water
        /// </summary>
        /// <returns>average temperature of water</returns>
        private double CalculateAverageTemp()
        {
            double tn = 0.5 * (condenser.dbWaterTemperature + res.dbOutWaterTemperature);
            return Math.Round(tn,2);
        }

        /// <summary>
        /// Calculate Galile coefficient
        /// </summary>
        /// <returns>Galile coefficient</returns>
        private double CalculateGalileCoefficient()
        {
            double Ga = (9.81 * Math.Pow(condenser.dbPipeLenght, 3)) / Math.Pow(condenser.dbKinematicViscosity, 2);
            return Math.Round(Ga,2);
        }

        /// <summary>
        /// Calculate Reynold coefficient
        /// </summary>
        /// <returns>Reynold coefficient</returns>
        private double CalculateReCoefficient()
        {
            double Re = 4 * res.dbWaterFlow / (3.14 * condenser.dbInterDiameter * condenser.dbDynamicViscosity);
            return Math.Round(Re,2);
        }

        /// <summary>
        /// Calculate Nusselt coefficient
        /// </summary>
        /// <returns>Nusselt coefficient</returns>
        private double CalculateNusseltCoefficient()
        {
            double Coefficient = (res.dbGalileCoefficient * condenser.dbPrandtlCoefficient * res.dbReCoefficient);
            double Nu = 0.01 * Math.Pow(Coefficient, 1.0 / 3.0);
            return Math.Round(Nu,2);
        }

        /// <summary>
        /// Calculate calorific coefficient to water
        /// </summary>
        /// <returns>calorific coefficient to water</returns>
        private double CalculateHeatCoefficient()
        {
            double alpha = res.dbNusseltCoefficient * condenser.dbHeatConductivityCoefficient / condenser.dbPipeLenght;
            return Math.Round(alpha,2);
        }

        /// <summary>
        /// Calculate heat density to water
        /// </summary>
        /// <returns>heat density to water</returns>
        private double CalculateHeatDensity()
        {
            double q2 = (res.dbDiffTemp - condenser.dbDiffTemp) / ((1 / res.dbHeatCoefficient) + condenser.dbThermalResistance);
            return Math.Round(q2,2);
        }

        /// <summary>
        /// Calculate area of internal surface
        /// </summary>
        /// <returns>area of internal surface</returns>
        private double CalculateHeatTransferArea()
        {
            double F2 = res.dbHeatCapacity * Math.Pow(10,3) / res.dbHeatDensity;
            return Math.Round(F2,2);
        }

        /// <summary>
        /// Calculate pipe pitch
        /// </summary>
        /// <returns>pipe pitch</returns>
        private double CalculatePipeArea()
        {
            double S = 1.3 * condenser.dbExterDiameter;
            return Math.Round(S,2);
        }

        /// <summary>
        /// Calculate big diagonal
        /// </summary>
        /// <returns>big diagonal</returns>
        private double CalculateDiagonal()
        {
            double can = res.dbHeatTransferArea / (condenser.dbInterDiameter * res.dbPipeArea * 4.9);
            double can3 = Math.Pow(can, 1.0 / 3.0);
            double m = 0.75 * can3;
            return Math.Round(m,0);
        }

        /// <summary>
        /// Calculate total of pipe
        /// </summary>
        /// <returns>total of pipe</returns>
        private double CalculatePipeNumber()
        {
            double n = 0.75 * Math.Pow(res.dbDiagonal, 2) + 0.25;
            return Math.Round(n,0);
        }

        /// <summary>
        /// Calculate diameter of pipe
        /// </summary>
        /// <returns>diameter of pipe</returns>
        private double CalculatePipeDiameter()
        {
            double D = res.dbDiagonal * res.dbPipeArea;
            return Math.Round(D,2);
        }

        /// <summary>
        /// Calculate lenght of pipe
        /// </summary>
        /// <returns>lenght of pipe</returns>
        private double CalculatePipeLenght()
        {
            double l = res.dbPipeDiameter * 4.9;
            return Math.Round(l,2);
        }
    }
}
